package net.guerlab.sdk.dingtalk.client;

import net.guerlab.sdk.dingtalk.DingTalkException;
import net.guerlab.sdk.dingtalk.request.AbstractDingTalkRequest;
import net.guerlab.sdk.dingtalk.request.AbstractSnsRequest;
import net.guerlab.sdk.dingtalk.response.AbstractResponse;
import net.guerlab.sdk.dingtalk.storage.DingTalkConfigStorage;

/**
 * 钉钉请求客户端接口
 *
 * @author guer
 */
public interface DingTalkClient {

    /**
     * 执行请求
     *
     * @param request
     *         请求
     * @param <RS>
     *         响应类型
     * @return 响应
     */
    <RS extends AbstractResponse> RS execute(AbstractDingTalkRequest<RS> request);

    /**
     * 执行请求
     *
     * @param request
     *         请求
     * @param <RS>
     *         响应类型
     * @return 响应
     */
    <RS extends AbstractResponse> RS execute(AbstractSnsRequest<RS> request);

    /**
     * 获取access_token, 不强制刷新access_token.
     *
     * @return 不强制刷新access_token
     * @throws DingTalkException
     *         当获取access_token失败时抛出DingTalkException
     * @see #getAccessToken(boolean)
     */
    default String getAccessToken() throws DingTalkException {
        return getAccessToken(false);
    }

    /**
     * 获取access_token
     *
     * @param forceRefresh
     *         强制刷新
     * @return 不强制刷新access_token
     * @throws DingTalkException
     *         当获取access_token失败时抛出DingTalkException
     */
    String getAccessToken(boolean forceRefresh) throws DingTalkException;

    /**
     * 获取AppKey
     *
     * @return AppKey
     */
    String getAppKey();

    /**
     * 获取AppSecret
     *
     * @return AppSecret
     */
    String getAppSecret();

    /**
     * 获取DingTalkConfigStorage 对象.
     *
     * @return DingTalkConfigStorage
     */
    DingTalkConfigStorage getDingTalkConfigStorage();

    /**
     * 设置 {@link DingTalkConfigStorage} 的实现
     *
     * @param dingTalkConfigStorage
     *         . dingTalkConfigStorage
     */
    void setDingTalkConfigStorage(DingTalkConfigStorage dingTalkConfigStorage);
}
